﻿using BaseFramework;
using LiteFramework.Security;
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;

namespace LiteFramework.Model
{
    /// <summary>
    /// 登陆请求信息
    /// </summary>
    [Serializable()]
    [ComVisible(true)]
    [DataContract]
    public sealed class LoginInfo : Bag
    {
        private byte[] _key = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        public LoginInfo()
        {
            this.SetData(LoginType.Default, SystemResources.APPROLE_NAME, null, null, null, null, DateTime.Now.ToString());
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        public LoginInfo(string userName, string password)
        {
            this.SetData(LoginType.Default, userName, password, null, null, null, null);
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="state">附加状态(智能卡/UKey的验证信息)。不为空时，视为使用附加安全验证</param>
        public LoginInfo(string userName, string password, object state)
        {
            this.SetData(LoginType.Default, userName, password, null, null, null, state);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="loginType">登陆类型（第三方授权登陆）</param>
        /// <param name="appId">应用Id</param>
        /// <param name="openId">授权用户Id</param>
        /// <param name="accessToken">授权用户Token</param>
        public LoginInfo(LoginType loginType, string openId, string accessToken)
        {
            this.SetData(loginType, null, null, openId, accessToken, null, null);
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="loginType">登陆类型（第三方授权登陆）</param>
        /// <param name="appId">应用Id</param>
        /// <param name="openId">授权用户Id</param>
        /// <param name="accessToken">授权用户Token</param>
        /// <param name="state">附加状态(智能卡/UKey的验证信息)。不为空时，视为使用附加安全验证</param>
        public LoginInfo(LoginType loginType, string openId, string accessToken, object state)
        {
            this.SetData(loginType, null, null, openId, accessToken, null, state);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="loginType">登陆类型（第三方授权登陆）</param>
        /// <param name="authorizationCode">授权Code</param>
        public LoginInfo(LoginType loginType, string authorizationCode)
        {
            this.SetData(loginType, null, null, null, null, authorizationCode, null);
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="loginType">登陆类型（第三方授权登陆）</param>
        /// <param name="authorizationCode">授权Code</param>
        /// <param name="state">附加状态(智能卡/UKey的验证信息)。不为空时，视为使用附加安全验证</param>
        public LoginInfo(LoginType loginType, string authorizationCode, object state)
        {
            this.SetData(loginType, null, null, null, null, authorizationCode, state);
        }

        #region Properties

        /// <summary>
        /// 登陆方式
        /// </summary>
        [DisplayName("登陆方式")]
        public LoginType LoginType { get { return (LoginType)this["LoginType"]; } }

        /// <summary>
        /// 跨域授权
        /// </summary>
        [DisplayName("跨域授权")]
        public bool IsApprole { get { return (UserName == SystemResources.APPROLE_NAME); } }

        /// <summary>
        /// 用户名/OpenId
        /// </summary>
        [DisplayName("用户名")]
        public string UserName
        {
            get { return DES.Decrypt((byte[])this["UserName"], _key); }
            set { this["UserName"] = DES.EncryptExt(value, _key); }
        }

        /// <summary>
        /// 密码/AccessToken
        /// </summary>
        [DisplayName("密码")]
        public string Password
        {
            get { return DES.Decrypt((byte[])this["Password"], _key); }
            set { this["Password"] = DES.EncryptExt(value, _key); }
        }

        /// <summary>
        /// OpenId
        /// </summary>
        [DisplayName("OpenId")]
        public string OpenId
        {
            get { return DES.Decrypt((byte[])this["OpenId"], _key); }
            set { this["OpenId"] = DES.EncryptExt(value, _key); }
        }

        /// <summary>
        /// AccessToken
        /// </summary>
        [DisplayName("AccessToken")]
        public string AccessToken
        {
            get { return DES.Decrypt((byte[])this["AccessToken"], _key); }
            set { this["AccessToken"] = DES.EncryptExt(value, _key); }
        }

        /// <summary>
        /// 第三方登陆授权码/AuthorizationCode（用此授权码换取用户登陆Token）
        /// </summary>
        [DisplayName("用户授权码")]
        public string AuthorizationCode { get { return DES.Decrypt((byte[])this["AuthorizationCode"], _key); } }

        /// <summary>
        /// 附加状态(智能卡/UKey的验证信息)。不为空时，视为使用附加安全验证
        /// </summary>
        [DisplayName("附加状态")]
        public object State { get { return this["State"]; } }

        /// <summary>
        /// 是否启用安全证书登陆
        /// </summary>
        [DisplayName("安全登陆")]
        public bool IsSecurity { get { return this.State != null; } }

        /// <summary>
        /// 帐套标识
        /// </summary>
        [DisplayName("帐套标识")]
        public string PrimeTag
        {
            get { return this.GetValue("PrimeTag", null); }
            set { this.SetValue("PrimeTag", value); }
        }

        /// <summary>
        /// 创建时间
        /// </summary>
        [DisplayName("创建时间")]
        public DateTime CreatedTime { get { return DateTime.Parse(DES.Decrypt((byte[])this["CreatedTime"], _key)); } }

        #endregion

        /// <summary>
        /// 验证登陆信息的有效性
        /// </summary>
        public void Validate()
        {
            double min = (DateTime.Now - this.CreatedTime).TotalMinutes;
            if (Math.Abs(min) > 5)
            {
                throw new AccessSecurityException("验证信息已经过期(偏差值测量: " + min.ToString() + " minutes)。");
            }

            if (IsApprole)
            {
                throw new AccessSecurityException("不能使用应用程序角色替代来进行验证。");
            }
        }

        private void SetData(LoginType loginType, string userName, string password, string openId, string accessToken, string authorizationCode, object state)
        {
            if (password == null)
                password = Guid.NewGuid().ToString("N").Substring(26); // 随机密码

            byte[] seed = LiteFramework.Security.MD5.CreateHash(password, HashType.MD5);

            Random rand = new Random();
            byte iv = (byte)rand.Next(seed.Length - 8);

            _key = new byte[8];
            Array.Copy(seed, iv, _key, 0, _key.Length);

            this["LoginType"] = loginType;
            this["UserName"] = DES.EncryptExt(userName, _key);
            this["Password"] = DES.EncryptExt(password, _key);
            this["OpenId"] = DES.EncryptExt(openId, _key);
            this["AccessToken"] = DES.EncryptExt(accessToken, _key);
            this["AuthorizationCode"] = DES.EncryptExt(authorizationCode, _key);
            this["State"] = state;
            this["CreatedTime"] = DES.EncryptExt(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), _key);
        }
    }

    /// <summary>
    /// 登陆方式
    /// </summary>
    public struct LoginType
    {
        public string Code { get; set; }
        public string Name { get; set; }

        public static bool operator ==(LoginType x, LoginType y)
        {
            return x.Code == y.Code;
        }
        public static bool operator !=(LoginType x, LoginType y)
        {
            return x.Code != y.Code;
        }

        public override bool Equals(object obj)
        {
            if (!base.Equals(obj)) return false;

            return this.Code == ((LoginType)obj).Code;
        }

        public override int GetHashCode()
        {
            if (this.Code != null) return this.Code.GetHashCode();
            return base.GetHashCode();
        }

        #region Predefine

        /// <summary>
        /// 默认，代表本系统
        /// </summary>
        public static LoginType Default
        {
            get
            {
                return new LoginType
                {
                    Code = null,
                    Name = null,
                };
            }
        }

        /// <summary>
        /// QQ
        /// </summary>
        public static LoginType QQ
        {
            get
            {
                return new LoginType
                {
                    Code = "QQ",
                    Name = "腾讯QQ",
                };
            }
        }
        /// <summary>
        /// 微信
        /// </summary>
        public static LoginType WeiXin
        {
            get
            {
                return new LoginType
                {
                    Code = "WeiXin",
                    Name = "微信",
                };
            }
        }
        /// <summary>
        /// 新浪微博
        /// </summary>
        public static LoginType WeiBo_Sina
        {
            get
            {
                return new LoginType
                {
                    Code = "WeiBo_Sina",
                    Name = "新浪微博",
                };
            }
        }

        #endregion

        public override string ToString()
        {
            return string.Format("{0}（{1}）", this.Name, this.Code);
        }
    }

    /// <summary>
    /// 登陆结果信息
    /// </summary>
    public struct LoginResult
    {
        public LoginResult(int userId, string securityToken, string error)
            : this()
        {
            UserId = userId;
            SecurityToken = securityToken;
            Error = error;
        }

        /// <summary>
        /// 用户Id
        /// </summary>
        public int UserId { get; set; }
        /// <summary>
        /// Token
        /// </summary>
        public string SecurityToken { get; set; }
        /// <summary>
        /// 错误信息（登陆失败时有效）
        /// </summary>
        public string Error { get; set; }
        /// <summary>
        /// 是否登陆成功
        /// </summary>
        public bool ok { get { return !string.IsNullOrEmpty(this.SecurityToken); } }
    }

    /// <summary>
    /// DES : 对称加密。加密强度：AES > 3DES > DES。
    /// <para>　　密码为8byte长度。</para>
    /// </summary>
    public class DES : SecurityAbs
    {
        #region 成员变量
        /// <summary>
        /// 密钥(8位,不足在后面补0)
        /// </summary>
        private const string _defaultPassword = "m8*^)LT$";
        /// <summary>
        /// 运算模式
        /// </summary>
        private static CipherMode _cipherMode = CipherMode.ECB;
        /// <summary>
        /// 填充模式
        /// </summary>
        private static PaddingMode _paddingMode = PaddingMode.PKCS7;
        /// <summary>
        /// 字符串采用的编码
        /// </summary>
        private static Encoding _encoding = Encoding.UTF8;
        #endregion

        #region 辅助方法
        /// <summary>
        /// 获取8byte (64bit)的密钥数据
        /// </summary>
        /// <param name="password">密码</param>
        /// <returns></returns>
        private static byte[] GetKeyArray(string password)
        {
            int keyLen = 8;

            if (password == null)
            {
                password = string.Empty;
            }

            if (password.Length < keyLen)
            {
                password = password.PadRight(keyLen, '0');
            }
            else if (password.Length > keyLen)
            {
                password = password.Substring(0, keyLen);
            }


            byte[] source = EncodingHelper.GetBytes(password, _encoding);
            byte[] result = new byte[keyLen];
            Buffer.BlockCopy(source, 0, result, 0, keyLen);

            return result;
        }

        /// <summary>
        /// 将字符数组转换成字符串
        /// </summary>
        /// <param name="inputData"></param>
        /// <returns></returns>
        private static string ConvertByteToString(byte[] inputData)
        {
            if (inputData == null)
                return null;

            StringBuilder sb = new StringBuilder(inputData.Length * 2);
            foreach (var b in inputData)
            {
                sb.Append(b.ToString("X2"));
            }
            return sb.ToString();
        }

        /// <summary>
        /// 将字符串转换成字符数组
        /// </summary>
        /// <param name="inputString"></param>
        /// <returns></returns>
        private static byte[] ConvertStringToByte(string inputString)
        {
            if (inputString == null)
                return null;

            if (inputString.Length < 2)
            {
                throw new ArgumentException();
            }

            int l = inputString.Length / 2;
            byte[] result = new byte[l];
            for (int i = 0; i < l; ++i)
            {
                result[i] = Convert.ToByte(inputString.Substring(2 * i, 2), 16);
            }

            return result;
        }
        #endregion

        /*
         * 加密时
         *  １.对于传入的字符串，通过EncodingHelper.GetBytes()方法，转换成字节流；
         *  ２.对字节流执行加密方法，并返回加密后的结果字节流；
         *  ３.再通过ConvertByteToString()方法，把返回的结果字节流，转换成16进制字符串
         * 
         * 解密时
         *  １.对于传入的字符串，通过ConvertStringToByte()方法，转换成字节流；
         *  ２.对字节流执行解密方法，并返回解密后的结果字节流；
         *  ３.再通过EncodingHelper.GetString()方法，把返回的结果字节流，转换成字符串原文
        */

        #region 加密

        /// <summary>
        /// 使用默认密码加密字符串(加密返回16进制字符串)
        /// </summary>
        /// <param name="inputString">需要加密的字符串</param>
        /// <returns>返回加密后的字符串（16进制字符串）</returns>
        public static string Encrypt(string inputString)
        {
            byte[] inputData = EncodingHelper.GetBytes(inputString, _encoding);
            byte[] encryptBytes = __fef68072_encrypt(inputData, GetKeyArray(_defaultPassword));
            string encryptString = ConvertByteToString(encryptBytes);
            return encryptString;
        }
        /// <summary>
        /// 使用默认密码加密字节数组(加密返回16进制字符串)
        /// </summary>
        /// <param name="inputData">需要加密的字节数组</param>
        /// <returns>返回加密后的字符串（16进制字符串）</returns>
        public static string Encrypt(byte[] inputData)
        {
            byte[] encryptBytes = __fef68072_encrypt(inputData, GetKeyArray(_defaultPassword));
            string encryptString = ConvertByteToString(encryptBytes);
            return encryptString;
        }

        /// <summary>
        /// 使用默认密码加密字符串
        /// </summary>
        /// <param name="inputString">需要加密的字符串</param>
        /// <returns>返回加密后的字节数组</returns>
        public static byte[] EncryptExt(string inputString)
        {
            byte[] inputData = EncodingHelper.GetBytes(inputString, _encoding);
            byte[] encryptBytes = __fef68072_encrypt(inputData, GetKeyArray(_defaultPassword));
            return encryptBytes;
        }
        /// <summary>
        /// 使用默认密码加密字节数组
        /// </summary>
        /// <param name="inputData">需要加密的字节数组</param>
        /// <returns>返回加密后的字节数组</returns>
        public static byte[] EncryptExt(byte[] inputData)
        {
            byte[] encryptBytes = __fef68072_encrypt(inputData, GetKeyArray(_defaultPassword));
            return encryptBytes;
        }


        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="inputString">需要加密的字符串</param>
        /// <param name="password">密码（最长8字节）</param>
        /// <returns>返回加密后的字符串（16进制字符串）</returns>
        public static string Encrypt(string inputString, string password)
        {
            byte[] inputData = EncodingHelper.GetBytes(inputString, _encoding);
            byte[] encryptBytes = __fef68072_encrypt(inputData, GetKeyArray(password));
            string encryptString = ConvertByteToString(encryptBytes);
            return encryptString;
        }
        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="inputString">需要加密的字符串</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回加密后的字符串（16进制字符串）</returns>
        public static string Encrypt(string inputString, byte[] password)
        {
            byte[] inputData = EncodingHelper.GetBytes(inputString, _encoding);
            byte[] encryptBytes = __fef68072_encrypt(inputData, password);
            string encryptString = ConvertByteToString(encryptBytes);
            return encryptString;
        }
        /// <summary>
        /// 加密字节数组
        /// </summary>
        /// <param name="inputData">需要加密的字节数组</param>
        /// <param name="password">密码（最长8字节）</param>
        /// <returns>返回加密后的字符串（16进制字符串）</returns>
        public static string Encrypt(byte[] inputData, string password)
        {
            byte[] encryptBytes = __fef68072_encrypt(inputData, GetKeyArray(password));
            string encryptString = ConvertByteToString(encryptBytes);
            return encryptString;
        }
        /// <summary>
        /// 加密字节数组
        /// </summary>
        /// <param name="inputData">需要加密的字节数组</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回加密后的字符串（16进制字符串）</returns>
        public static string Encrypt(byte[] inputData, byte[] password)
        {
            byte[] encryptBytes = __fef68072_encrypt(inputData, password);
            string encryptString = ConvertByteToString(encryptBytes);
            return encryptString;
        }

        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="inputString">需要加密的字符串</param>
        /// <param name="password">密码（最长8字节）</param>
        /// <returns>返回加密后的字节数组</returns>
        public static byte[] EncryptExt(string inputString, string password)
        {
            byte[] inputData = EncodingHelper.GetBytes(inputString, _encoding);
            byte[] encryptBytes = __fef68072_encrypt(inputData, GetKeyArray(password));
            return encryptBytes;
        }
        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="inputString">需要加密的字符串</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回加密后的字节数组</returns>
        public static byte[] EncryptExt(string inputString, byte[] password)
        {
            byte[] inputData = EncodingHelper.GetBytes(inputString, _encoding);
            byte[] encryptBytes = __fef68072_encrypt(inputData, password);
            return encryptBytes;
        }
        /// <summary>
        /// 加密字节数组
        /// </summary>
        /// <param name="inputData">需要加密的字节数组</param>
        /// <param name="password">密码（最长8字节）</param>
        /// <returns>返回加密后的字节数组</returns>
        public static byte[] EncryptExt(byte[] inputData, string password)
        {
            byte[] encryptBytes = __fef68072_encrypt(inputData, GetKeyArray(password));
            return encryptBytes;
        }
        /// <summary>
        /// 加密字节数组
        /// </summary>
        /// <param name="inputData">需要加密的字节数组</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回加密后的字节数组</returns>
        public static byte[] EncryptExt(byte[] inputData, byte[] password)
        {
            byte[] encryptBytes = __fef68072_encrypt(inputData, password);
            return encryptBytes;
        }


        /// <summary>
        /// 加密字节数组
        /// </summary>
        /// <param name="inputData">需要加密的字节数组</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回加密后的字节数组</returns>
        public static byte[] __fef68072_encrypt(byte[] inputData, byte[] password)
        {
            if (inputData == null)
                return null;

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            des.Key = password;
            des.Mode = _cipherMode;
            des.Padding = _paddingMode;
            ICryptoTransform transform = des.CreateEncryptor();
            byte[] data = null;
            try
            {
                data = transform.TransformFinalBlock(inputData, 0, inputData.Length);
            }
            catch
            {
                throw;
            }
            finally
            {
                des.Clear();
            }

            return data;
        }

        #endregion

        #region 解密

        /// <summary>
        /// 使用默认密码解密字符串（解密16进制字符串）
        /// </summary>
        /// <param name="inputString">需要解密的字符串（16进制字符串）</param>
        /// <returns>返回解密后的字符串</returns>
        public static string Decrypt(string inputString)
        {
            byte[] inputData = ConvertStringToByte(inputString);
            byte[] decryptBytes = __fef68072_decrypt(inputData, GetKeyArray(_defaultPassword));
            string decryptString = EncodingHelper.GetString(decryptBytes, _encoding);
            return decryptString;
        }
        /// <summary>
        /// 使用默认密码解密字节数组
        /// </summary>
        /// <param name="inputData">需要解密的字节数组</param>
        /// <returns>返回解密后的字符串</returns>
        public static string Decrypt(byte[] inputData)
        {
            byte[] decryptBytes = __fef68072_decrypt(inputData, GetKeyArray(_defaultPassword));
            string decryptString = EncodingHelper.GetString(decryptBytes, _encoding);
            return decryptString;
        }

        /// <summary>
        /// 使用默认密码解密字符串（解密16进制字符串）
        /// </summary>
        /// <param name="inputString">需要解密的字符串（16进制字符串）</param>
        /// <returns>返回解密后的字节数组</returns>
        public static byte[] DecryptExt(string inputString)
        {
            byte[] inputData = ConvertStringToByte(inputString);
            byte[] decryptBytes = __fef68072_decrypt(inputData, GetKeyArray(_defaultPassword));
            return decryptBytes;
        }
        /// <summary>
        /// 使用默认密码解密字节数组
        /// </summary>
        /// <param name="inputData">需要解密的字节数组</param>
        /// <returns>返回解密后的字节数组</returns>
        public static byte[] DecryptExt(byte[] inputData)
        {
            byte[] decryptBytes = __fef68072_decrypt(inputData, GetKeyArray(_defaultPassword));
            return decryptBytes;
        }



        /// <summary>
        /// 解密字符串（解密16进制字符串）
        /// </summary>
        /// <param name="inputString">需要解密的字符串（16进制字符串）</param>
        /// <param name="password">密码（最长8字节）</param>
        /// <returns>返回解密后的字符串</returns>
        public static string Decrypt(string inputString, string password)
        {
            byte[] inputData = ConvertStringToByte(inputString);
            byte[] decryptBytes = __fef68072_decrypt(inputData, GetKeyArray(password));
            string decryptString = EncodingHelper.GetString(decryptBytes, _encoding);
            return decryptString;
        }
        /// <summary>
        /// 使用默认密码解密字符串（解密16进制字符串）
        /// </summary>
        /// <param name="inputString">需要解密的字符串（16进制字符串）</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回解密后的字符串</returns>
        public static string Decrypt(string inputString, byte[] password)
        {
            byte[] inputData = ConvertStringToByte(inputString);
            byte[] decryptBytes = __fef68072_decrypt(inputData, password);
            string decryptString = EncodingHelper.GetString(decryptBytes, _encoding);
            return decryptString;
        }
        /// <summary>
        /// 使用默认密码解密字节数组
        /// </summary>
        /// <param name="inputData">需要解密的字节数组</param>
        /// <param name="password">密码（最长8字节）</param>
        /// <returns>返回解密后的字符串</returns>
        public static string Decrypt(byte[] inputData, string password)
        {
            byte[] decryptBytes = __fef68072_decrypt(inputData, GetKeyArray(password));
            string decryptString = EncodingHelper.GetString(decryptBytes, _encoding);
            return decryptString;
        }
        /// <summary>
        /// 解密字节数组
        /// </summary>
        /// <param name="inputData">要解密的字节数组</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回解密后的字符串</returns>
        public static string Decrypt(byte[] inputData, byte[] password)
        {
            byte[] decryptBytes = __fef68072_decrypt(inputData, password);
            string decryptString = EncodingHelper.GetString(decryptBytes, _encoding);
            return decryptString;
        }


        /// <summary>
        /// 使用默认密码解密字符串（解密16进制字符串）
        /// </summary>
        /// <param name="inputString">需要解密的字符串（16进制字符串）</param>
        /// <param name="password">密码（最长8字节）</param>
        /// <returns>返回解密后的字节数组</returns>
        public static byte[] DecryptExt(string inputString, string password)
        {
            byte[] inputData = ConvertStringToByte(inputString);
            byte[] decryptBytes = __fef68072_decrypt(inputData, GetKeyArray(password));
            return decryptBytes;
        }
        /// <summary>
        /// 使用默认密码解密字符串（解密16进制字符串）
        /// </summary>
        /// <param name="inputString">需要解密的字符串（16进制字符串）</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回解密后的字节数组</returns>
        public static byte[] DecryptExt(string inputString, byte[] password)
        {
            byte[] inputData = ConvertStringToByte(inputString);
            byte[] decryptBytes = __fef68072_decrypt(inputData, password);
            return decryptBytes;
        }
        /// <summary>
        /// 解密字节数组
        /// </summary>
        /// <param name="inputData">要解密的字节数组</param>
        /// <param name="password">密码（最长8字节）</param>
        /// <returns>返回解密后的字节数组</returns>
        public static byte[] DecryptExt(byte[] inputData, string password)
        {
            byte[] decryptBytes = __fef68072_decrypt(inputData, GetKeyArray(password));
            return decryptBytes;
        }
        /// <summary>
        /// 解密字节数组
        /// </summary>
        /// <param name="inputData">要解密的字节数组</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回解密后的字节数组</returns>
        public static byte[] DecryptExt(byte[] inputData, byte[] password)
        {
            byte[] decryptBytes = __fef68072_decrypt(inputData, password);
            return decryptBytes;
        }


        /// <summary>
        /// 解密字节数组
        /// </summary>
        /// <param name="inputData">要解密的字节数组</param>
        /// <param name="password">密码（固定8字节）</param>
        /// <returns>返回解密后的字节数组</returns>
        private static byte[] __fef68072_decrypt(byte[] inputData, byte[] password)
        {
            if (inputData == null)
                return null;

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            des.Key = password;
            des.Mode = _cipherMode;
            des.Padding = _paddingMode;
            ICryptoTransform transform = des.CreateDecryptor();
            byte[] data = null;
            try
            {
                data = transform.TransformFinalBlock(inputData, 0, inputData.Length);
            }
            catch
            {
                throw;
            }
            finally
            {
                des.Clear();
            }

            return data;
        }

        #endregion
    }

    /// <summary>
    /// 所有加密算法的顶层基类
    /// </summary>
    public abstract class SecurityAbs
    {
        protected const string __defaultKEY = "hykon.cn";
        protected const string __defaultIV = "~2@,5*eL";


        #region CreateIV

        /// <summary>
        /// 生成IV。加密的强随机数
        /// </summary>
        /// <returns></returns>
        public static string CreateIV()
        {
            return CreateIV(0x10);
        }

        /// <summary>
        /// 生成IV。加密的强随机数
        /// </summary>
        /// <returns></returns>
        public static string CreateIV(int len)
        {
            byte[] data = new byte[len];
            new RNGCryptoServiceProvider().GetBytes(data);
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < len; i++)
            {
                double num = ((double)data[i]) / 256.0;
                data[i] = (byte)((num * 76.0) + 47.0);
                builder.Append(Convert.ToString(data[i], len).ToUpper());
            }

            return builder.ToString();
        }

        #endregion


        /// <summary>
        /// string转换为byte数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        protected static byte[] getBytes(string s)
        {
            return getBytes(s, null);
        }
        /// <summary>
        /// string转换为byte数组
        /// </summary>
        /// <param name="s"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        protected static byte[] getBytes(string s, Encoding encoding)
        {
            if (encoding == null) encoding = Encoding.Default;

            if (s == null)
            {
                s = string.Empty;
            }
            s = s.PadRight(8, '@');//.Substring(0, 8);

            char[] chars = s.ToCharArray();// new char[] { s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7] };
            return encoding.GetBytes(chars);
        }

        /// <summary>
        /// 字符串转byte数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        protected static byte[] Base64StringToBytes(string s)
        {
            if (s == null)
            {
                s = string.Empty;
            }

            return Convert.FromBase64String(s);
        }

        protected static string BytesToBase64String(byte[] buffer)
        {
            if (buffer != null)
                return Convert.ToBase64String(buffer);

            return null;
        }
    }
}